package service

import (
	sqlc "bgs/db/sqlc"
	"bgs/util"
	"context"
	"database/sql"
)

// EnsureBrandStat 确保BrandStat对于一个品牌始终有一条记录
func (s *BrandServiceImp) EnsureBrandStat(ctx context.Context, q *sqlc.Queries, withLock bool, brandID int64) (brandStat sqlc.BrandStat, err error) {
	slog := util.NewContextLogger(ctx, s.slog)

	var sqlErr error
	if withLock {
		brandStat, sqlErr = q.GetBrandStatByBrandIDToLock(ctx, brandID)
	} else {
		brandStat, sqlErr = q.GetBrandStatByBrandID(ctx, brandID)
	}

	if sqlErr != nil {
		if sql.ErrNoRows != sqlErr {
			err = sqlErr
			return
		}
		slog.Infof("找不到品牌统计记录")
		brandStat, err = q.UpsertBrandStat(ctx, sqlc.UpsertBrandStatParams{
			BrandID:                    brandID,
			FansCount:                  0,
			AdminCount:                 0,
			PublishActivityCount:       0,
			SpokesmanCount:             0,
			EndorseRequestToAuditCount: 0,
		})
		if err != nil {
			return
		}
	}
	slog.Infof("确保BrandStat对于一个品牌始终有一条记录并返回 ok")
	return
}

// UpdateBrandStatFansCountSinceUpsertBrandFan (主动,品牌统计更新粉丝数量)
func (s *BrandServiceImp) UpdateBrandStatFansCountSinceUpsertBrandFan(ctx context.Context, q *sqlc.Queries, brandID int64) (err error) {
	slog := util.NewContextLogger(ctx, s.slog)

	brandStatLocked, err := s.EnsureBrandStat(ctx, q, true, brandID)
	if err != nil {
		return
	}
	slog.Infof("1、brand_fans-确保获取锁定的品牌(%d)统计记录 ok", brandID)
	slog.Infof("2、brand_fans 更新前fans_count(%d) ok", brandStatLocked.FansCount)

	fansCount, err := q.AggrBrandFansCountByBrandID(ctx, brandID)
	if err != nil {
		return
	}
	slog.Infof("3、统计当前品牌的fans_count ok")

	err = q.UpdateBrandStatFansCountByBrandID(ctx, sqlc.UpdateBrandStatFansCountByBrandIDParams{
		BrandID:   brandID,
		FansCount: int32(fansCount),
	})
	if err != nil {
		return
	}
	slog.Infof("4、brand_fans 更新前fans_count(%d) ok", fansCount)

	slog.Infof("=品牌统计更新粉丝数量 ok")

	return
}

// UpdateBrandStatAdminCountSinceUpsertBrandAdmin (主动,品牌统计更新管理员数量)
func (s *BrandServiceImp) UpdateBrandStatAdminCountSinceUpsertBrandAdmin(ctx context.Context, q *sqlc.Queries, brandID int64) (err error) {
	slog := util.NewContextLogger(ctx, s.slog)

	brandStatLocked, err := s.EnsureBrandStat(ctx, q, true, brandID)
	if err != nil {
		return
	}
	slog.Infof("1、brand_admins-确保获取锁定的品牌(%d)统计记录 ok", brandID)
	slog.Infof("2、brand_admins 更新前admin_count(%d) ok", brandStatLocked.AdminCount)

	adminCount, err := q.AggrBrandAdminCountByBrandID(ctx, brandID)
	if err != nil {
		return
	}
	slog.Infof("3、统计当前品牌的fans_count ok")

	err = q.UpdateBrandStatAdminCountByBrandID(ctx, sqlc.UpdateBrandStatAdminCountByBrandIDParams{
		BrandID:    brandID,
		AdminCount: int32(adminCount),
	})
	if err != nil {
		return
	}
	slog.Infof("4、brand_admins 更新后admin_count(%d) ok", adminCount)

	slog.Infof("=品牌统计更新管理员数量 ok")

	return
}

// UpdateBrandStatSpokesmanCountSinceUpsertBrandSpokesman (主动,品牌统计更新代言人B数量)
func (s *BrandServiceImp) UpdateBrandStatSpokesmanCountSinceUpsertBrandSpokesman(ctx context.Context, q *sqlc.Queries, brandID int64) (err error) {
	slog := util.NewContextLogger(ctx, s.slog)

	brandStatLocked, err := s.EnsureBrandStat(ctx, q, true, brandID)
	if err != nil {
		return
	}
	slog.Infof("1、brand_spokesmans-确保获取锁定的品牌(%d)统计记录 ok", brandID)
	slog.Infof("2、brand_spokesmans 更新前spokesman_count(%d) ok", brandStatLocked.SpokesmanCount)

	spokesmanCount, err := q.AggrBrandSpokesmanCountByBrandID(ctx, brandID)
	if err != nil {
		return
	}
	slog.Infof("3、统计当前品牌的spokesman_count ok")

	err = q.UpdateBrandStatSpokesmanCountByBrandID(ctx, sqlc.UpdateBrandStatSpokesmanCountByBrandIDParams{
		BrandID:        brandID,
		SpokesmanCount: int32(spokesmanCount),
	})
	if err != nil {
		return
	}
	slog.Infof("4、brand_spokesmans 更新后spokesman_count(%d) ok", spokesmanCount)

	slog.Infof("=品牌统计更新代言人B数量 ok")

	return
}

// UpdateBrandStatEndorseRequestCountSinceCreateBrandEndorsePendingRequest (主动,品牌统计更新未审核的代言人申请数量)
func (s *BrandServiceImp) UpdateBrandStatEndorseRequestCountSinceCreateBrandEndorsePendingRequest(ctx context.Context, q *sqlc.Queries, brandID int64) (err error) {
	slog := util.NewContextLogger(ctx, s.slog)

	brandStatLocked, err := s.EnsureBrandStat(ctx, q, true, brandID)
	if err != nil {
		return
	}
	slog.Infof("1、brand_endorse_request-确保获取锁定的品牌(%d)统计记录 ok", brandID)
	slog.Infof("2、brand_endorse_request 更新前pending_endorse_request_count(%d) ok", brandStatLocked.EndorseRequestToAuditCount)

	endorseRequestToAuditCount, err := q.AggrBrandEndorseRequestPendingCountByBrandID(ctx, brandID)
	if err != nil {
		return
	}
	slog.Infof("3、统计当前品牌的pending_endorse_request_count ok")

	err = q.UpdateBrandStatSpokesmanCountByBrandID(ctx, sqlc.UpdateBrandStatSpokesmanCountByBrandIDParams{
		BrandID:        brandID,
		SpokesmanCount: int32(endorseRequestToAuditCount),
	})
	if err != nil {
		return
	}
	slog.Infof("4、brand_endorse_request 更新后pending_endorse_request_count(%d) ok", endorseRequestToAuditCount)

	slog.Infof("=品牌统计更新代言人B数量 ok")

	return
}

// UpdateBrandStatDistributorCountSinceUpsertBrandDistributor (主动,品牌统计更新分销员B数量)
func (s *BrandServiceImp) UpdateBrandStatDistributorCountSinceUpsertBrandDistributor(ctx context.Context, q *sqlc.Queries, brandID int64) (err error) {
	slog := util.NewContextLogger(ctx, s.slog)

	brandStatLocked, err := s.EnsureBrandStat(ctx, q, true, brandID)
	if err != nil {
		return
	}
	slog.Infof("1、brand_distributors-确保获取锁定的品牌(%d)统计记录 ok", brandID)
	slog.Infof("1、brand_distributors 更新前distributor_count(%d) ok", brandStatLocked.DistributorCount)

	distributorCount, err := q.AggrBrandDistributorCountByBrandID(ctx, brandID)
	if err != nil {
		return
	}
	slog.Infof("3、统计当前品牌的distributor_count ok")

	err = q.UpdateBrandStatDistributorCountByBrandID(ctx, sqlc.UpdateBrandStatDistributorCountByBrandIDParams{
		BrandID:          brandID,
		DistributorCount: int32(distributorCount),
	})
	if err != nil {
		return
	}
	slog.Infof("4、brand_distributors 更新后distributor_count(%d) ok", distributorCount)

	slog.Infof("=品牌统计更新分销员B数量 ok")

	return
}

// UpdateBrandStatDistributeRequestCountSinceCreateBrandDistributePendingRequest (主动,品牌统计更新未审核的分销员人申请数量)
func (s *BrandServiceImp) UpdateBrandStatDistributeRequestCountSinceCreateBrandDistributePendingRequest(ctx context.Context, q *sqlc.Queries, brandID int64) (err error) {
	slog := util.NewContextLogger(ctx, s.slog)

	brandStatLocked, err := s.EnsureBrandStat(ctx, q, true, brandID)
	if err != nil {
		return
	}
	slog.Infof("1、brand_distributors-确保获取锁定的品牌(%d)统计记录 ok", brandID)
	slog.Infof("2、brand_distributors 更新前pending_distribute_request_count(%d) ok", brandStatLocked.DistributeRequestToAuditCount)

	distributeRequestToAuditCount, err := q.AggrBrandDistributeRequestPendingCountByBrandID(ctx, brandID)
	if err != nil {
		return
	}
	slog.Infof("3、统计当前品牌的distributor_count ok")

	err = q.UpdateBrandStatDistributorCountByBrandID(ctx, sqlc.UpdateBrandStatDistributorCountByBrandIDParams{
		BrandID:          brandID,
		DistributorCount: int32(distributeRequestToAuditCount),
	})
	if err != nil {
		return
	}
	slog.Infof("4、brand_distributors 更新后pending_distribute_request_count(%d) ok", distributeRequestToAuditCount)

	slog.Infof("=品牌统计更新分销员B数量 ok")

	return
}

// UpdateBrandStatPublishActivityCountSinceBrandOwnActivityPublished (主动,品牌统计自身发布的活动数量)
func (s *BrandServiceImp) UpdateBrandStatPublishActivityCountSinceBrandOwnActivityPublished(ctx context.Context, q *sqlc.Queries, brandID int64, asFeatureTypes []string) (err error) {
	slog := util.NewContextLogger(ctx, s.slog)

	brandStatLocked, err := s.EnsureBrandStat(ctx, q, true, brandID)
	if err != nil {
		return
	}
	slog.Infof("1、activities-确保获取锁定的品牌(%d)统计记录 ok", brandID)
	slog.Infof("2、activities 更新前publish_activity_count(%d) ok", brandStatLocked.PublishActivityCount)

	publishActivityCount, err := q.AggrActivityCountPublishedOfBrandOwnByBrandID(ctx, sqlc.AggrActivityCountPublishedOfBrandOwnByBrandIDParams{
		BrandID:        brandID,
		AsFeatureTypes: asFeatureTypes,
	})
	if err != nil {
		return
	}
	slog.Infof("3、统计当前品牌的publishActivityCount ok")

	err = q.UpdateBrandStatPublishActivityCountByBrandID(ctx, sqlc.UpdateBrandStatPublishActivityCountByBrandIDParams{
		BrandID:              brandID,
		PublishActivityCount: int32(publishActivityCount),
	})
	if err != nil {
		return
	}
	slog.Infof("4、activities 更新前publish_activity_count(%d) ok", publishActivityCount)

	slog.Infof("=品牌统计自身发布的活动数量 ok")

	return
}
